package com.wzcl.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.wzcl.app.dao.model.ActivityGroup;
import com.wzcl.app.dao.model.ActivityGroupPromotion;
import com.wzcl.app.dao.model.AppUser;
import com.wzcl.app.dao.repository.ActivityGroupRepository;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.common.WZCL;
import com.wzcl.app.model.dto.ActivityGroupDto;
import com.wzcl.app.model.vo.BaseVo;
import com.wzcl.app.service.ActivityGroupPromotionService;
import com.wzcl.app.service.ActivityGroupService;
import com.wzcl.app.utils.RedisUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

@Log4j2
@Service
public class ActivityGroupServiceImpl implements ActivityGroupService {
    public static final String GROUP_EXPIRED_KEY = "GROUP_EXPIRED_";

    @Autowired
    private ActivityGroupRepository repository;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ActivityGroupPromotionService activityGroupPromotionService;

    @Override
    public ActivityGroup createActivityGroup(AppUser user, Integer promotionId, Integer commodityId) {
        ActivityGroupPromotion promotion = activityGroupPromotionService.getAndCheckById(promotionId);
        ActivityGroup activityGroup = new ActivityGroup();
        activityGroup.setActivityId(promotion.getActivityId());
        activityGroup.setPromotionId(promotion.getId());
        activityGroup.setCommodityId(commodityId);
        activityGroup.setMax(promotion.getGroupSize().intValue());
        activityGroup.setSize(1);
        activityGroup.setGroupState(WZCL.GROUP_STATE.PROCESSING);
        activityGroup.setUserPhone(user.getPhone());
        activityGroup.setUserName(user.getNickName());
        String headIcon = user.getHeadIcon();
        activityGroup.setHeadIcon(StringUtils.isBlank(headIcon)? BaseVo.DEFAULT_AVATAR_IMAGE:headIcon);
        Long time = promotion.getTime();
        activityGroup.setExpiredTime(new Date(new Date().getTime() + time * 1000));
        activityGroup = repository.save(activityGroup);
        //设置组团的过期时间
        redisUtil.set(GROUP_EXPIRED_KEY+activityGroup.getId(),activityGroup.getId(), time);
        return activityGroup;
    }

    @Override
    public ActivityGroup joinActivityGroup(AppUser appUser, Integer groupId) {
        //判断是否重复参团
        ActivityGroup activityGroup = getAndCheckById(groupId);
        LinkedHashMap<String, String> map = new LinkedHashMap<>();
        map.put("userPhone",appUser.getPhone());
        map.put("userName",appUser.getNickName());
        String headIcon = appUser.getHeadIcon();
        map.put("headIcon",StringUtils.isBlank(headIcon)? BaseVo.DEFAULT_AVATAR_IMAGE:headIcon);
        activityGroup.getMembers().add(JSON.toJSONString(map));
        activityGroup.setSize(activityGroup.getSize() + 1);
        if(activityGroup.getSize() >= activityGroup.getMax()){
            activityGroup.setGroupState(WZCL.GROUP_STATE.SUCCESS);
        }
        activityGroup = repository.save(activityGroup);
        return activityGroup;
    }

    @Override
    public List<ActivityGroup> getActivityGroupList(ActivityGroupDto activityGroupDto) {
        return repository.findAll(getSpecification(activityGroupDto),activityGroupDto.getSort());
    }

    @Override
    public ActivityGroup getAndCheckById(Integer id) {
        if(id == null){
            throw new BusinessException(CodeMsg.COMMODITY_NOT_EXIST, "缺少目标团ID");
        }
        ActivityGroup group = repository.findById(id).orElse(null);
        if(group == null){
            throw new BusinessException(CodeMsg.ACTIVITY_GROUP_NOT_EXIST);
        }
        return group;
    }

    public Specification<ActivityGroup> getSpecification(ActivityGroupDto activityGroupDto) {
        return new Specification<ActivityGroup>() {
            @Override
            public Predicate toPredicate(Root<ActivityGroup> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                if (activityGroupDto.getActivityId() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("activityId"), activityGroupDto.getActivityId()));
                }
                if (activityGroupDto.getCommodityId() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("commodityId"), activityGroupDto.getCommodityId()));
                }
                if (activityGroupDto.getUserPhone() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("userPhone"), activityGroupDto.getUserPhone()));
                }
                if (activityGroupDto.getGroupState() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("groupState"), activityGroupDto.getGroupState()));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }

    public void save(ActivityGroup group){
        repository.save(group);
    }
}
